package org.example;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.nio.file.Paths;
import java.sql.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LogProcessor {
    private static final ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) {
        // 获取当前目录下的logs文件夹路径
        String currentDir = System.getProperty("user.dir");
        String logsDir = Paths.get(currentDir, "logs").toString();

        File logsDirFile = new File(logsDir);
        if (!logsDirFile.exists() || !logsDirFile.isDirectory()) {
            System.out.println("logs文件夹不存在: " + logsDir);
            return;
        }

        // 存储所有日志数据
        Map<String, List<JsonNode>> allJsonData = new HashMap<>();

        // 遍历logs文件夹下的所有子文件夹
        File[] dateFolders = logsDirFile.listFiles(File::isDirectory);
        if (dateFolders != null) {
            for (File dateFolder : dateFolders) {
                String dateFolderName = dateFolder.getName();

                // 检查文件夹名是否符合日期格式
                try {
                    DateTimeFormatter.ofPattern("yyyy-MM-dd").parse(dateFolderName);

                    // 构建.gsws.log文件路径
                    File logFile = new File(dateFolder, ".gsws.log");

                    if (logFile.exists() && logFile.isFile()) {
                        System.out.println("正在处理: " + dateFolderName + "/.gsws.log");

                        // 读取JSON数据
                        List<JsonNode> jsonObjects = readJsonFile(logFile);

                        allJsonData.put(dateFolderName, jsonObjects);
                        System.out.println("成功读取 " + jsonObjects.size() + " 条JSON记录");
                    } else {
                        System.out.println("文件不存在: " + logFile.getAbsolutePath());
                    }
                } catch (DateTimeParseException e) {
                    System.out.println("跳过非日期格式文件夹: " + dateFolderName);
                }
            }
        }

        // 将日志数据插入到数据库
        insertLogsToDb(allJsonData);
    }

    /**
     * 读取JSON文件中的每一行
     *
     * @param file JSON文件
     * @return 包含所有JSON对象的列表
     */
    private static List<JsonNode> readJsonFile(File file) {
        List<JsonNode> jsonObjects = new ArrayList<>();

        try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
            String line;
            int lineNumber = 1;

            while ((line = reader.readLine()) != null) {
                try {
                    line = line.trim();
                    if (!line.isEmpty()) {
                        JsonNode jsonObj = objectMapper.readTree(line);
                        jsonObjects.add(jsonObj);
                    }
                } catch (Exception e) {
                    System.out.println("第 " + lineNumber + " 行JSON解析错误: " + e.getMessage());
                    System.out.println("错误行内容: " + line);
                }
                lineNumber++;
            }
        } catch (Exception e) {
            System.out.println("读取文件时发生错误: " + e.getMessage());
        }

        return jsonObjects;
    }

    /**
     * 将日志数据插入到数据库中
     *
     * @param logsData 包含所有日期文件夹下日志数据的Map
     * @return 成功插入的记录数量
     */
    private static int insertLogsToDb(Map<String, List<JsonNode>> logsData) {
        Connection conn = null;
        PreparedStatement stmt = null;
        int insertedCount = 0;

        try {
            // 连接到MySQL数据库
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306?useSSL=false&allowPublicKeyRetrieval=true",
                    "root",  // 替换为你的数据库用户名
                    "141421"  // 替换为你的数据库密码
            );

            // 创建数据库和表（如果不存在）
            Statement createStmt = conn.createStatement();
            createStmt.execute("CREATE DATABASE IF NOT EXISTS logs");
            createStmt.execute("USE logs");
            createStmt.execute(
                    "CREATE TABLE IF NOT EXISTS log (" +
                            "  msg TEXT," +
                            "  time TIMESTAMP" +
                            ")"
            );
            createStmt.close();

            // 准备插入语句
            String insertQuery = "INSERT INTO log (msg, time) VALUES (?, ?)";
            stmt = conn.prepareStatement(insertQuery);

            // 遍历所有日志数据
            for (List<JsonNode> records : logsData.values()) {
                for (JsonNode record : records) {
                    if (record.has("msg") && record.has("time")) {
                        try {
                            // 解析时间字符串为Timestamp对象
                            String timeStr = record.get("time").asText();
                            // 移除时区信息，因为MySQL TIMESTAMP不支持时区
                            timeStr = timeStr.replaceAll("\\+\\d{2}:\\d{2}$", "");
                            LocalDateTime dateTime = LocalDateTime.parse(timeStr, DateTimeFormatter.ISO_DATE_TIME);
                            Timestamp timestamp = Timestamp.valueOf(dateTime);

                            // 插入数据
                            stmt.setString(1, record.get("msg").asText());
                            stmt.setTimestamp(2, timestamp);
                            stmt.executeUpdate();
                            insertedCount++;
                        } catch (Exception e) {
                            System.out.println("时间解析错误: " + record.get("time").asText() + ", 错误: " + e.getMessage());
                        }
                    }
                }
            }

            System.out.println("成功插入 " + insertedCount + " 条记录到数据库");
            return insertedCount;

        } catch (SQLException e) {
            System.out.println("数据库错误: " + e.getMessage());
            return 0;
        } finally {
            try {
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
                System.out.println("数据库连接已关闭");
            } catch (SQLException e) {
                System.out.println("关闭数据库连接时发生错误: " + e.getMessage());
            }
        }
    }
}